package tools

import (
	"gopkg.in/mgo.v2/bson"
	"fmt"
	"encoding/json"
	"io"
	"io/ioutil"
	"hub.hddznet.com/app/framework/errs"
	"reflect"
	"os/exec"
)

func Guid() string {
	return bson.NewObjectId().Hex()
}

func PtrOfInt(i int) *int {
	return &i
}

func PtrOfString(i string) *string {
	return &i
}

func PtrOfInt64(i int64) *int64 {
	return &i
}

func PtrOfFloat64(i float64) *float64 {
	return &i
}

func InterfaceOfString(i interface{}) string {

	if i == nil {
		return ""
	}

	return i.(string)
}

func InterfaceOfInt64(i interface{}) int64 {

	if i == nil {
		return 0
	}
	return i.(int64)
}

// 将字符串转换为map[string]interface{}
func TsnJsonStringToMap(str string) (map[string]interface{}, error) {
	re := map[string]interface{}{}
	err := json.Unmarshal([]byte(str), &re)
	return re, err
}

// 将struct转换为map[string]interface{}
func TsnObjToMap(obj interface{}) (map[string]interface{}, error) {
	if obj == nil {
		return map[string]interface{}{}, nil
	}
	data, err := json.Marshal(obj)
	if err != nil {
		return nil, errs.JsonStrfyErr(data)
	}
	result := map[string]interface{}{}
	err = json.Unmarshal(data, &result)
	if err != nil {
		return nil, errs.JsonByteToObjErr(err.Error())
	}
	return result, err
}

// 判断字符串是否存在与数组中
func StrContains(src []string, tag string) bool {
	for _, s := range src {
		if s == tag {
			return true
		}
	}
	return false
}

// 以json格式输出struct对象
func PrintStruct(obj interface{}) {
	r, err := json.Marshal(obj)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(r))
}

// 从io刘中读取到数据，并且格式化为json格式
func MapByReader(reader io.Reader) (map[string]interface{}, error) {
	b, _ := ioutil.ReadAll(reader)
	r := map[string]interface{}{}
	if len(b) == 0 {
		return r, nil
	}
	err := json.Unmarshal(b, &r)
	return r, err
}

func MapByInterface(obj interface{}) map[string]interface{} {
	ty := reflect.TypeOf(obj)
	vl := reflect.ValueOf(obj)
	if ty.Kind() == reflect.Ptr {
		ty = ty.Elem()
		vl = vl.Elem()
	}
	if ty.Kind() != reflect.Map {
		panic("传入的数据类型不对，需要为map类型")
	}
	result := map[string]interface{}{}
	for _, key := range vl.MapKeys() {
		result[key.String()] = vl.MapIndex(key).Interface()
	}
	return result
}

func Cmd(cmd string, arg ... string) []byte {
	c := exec.Command(cmd, arg...)
	// 获取输出对象，可以从该对象中读取输出结果
	stdout, err := c.StdoutPipe()
	if err != nil {
		return nil
	}
	// 保证关闭输出流
	defer stdout.Close()
	// 运行命令
	if err := c.Start(); err != nil {
		return nil
	}
	// 读取输出结果
	opBytes, err := ioutil.ReadAll(stdout)
	if err != nil {
		return nil
	}
	return opBytes
}
